package com.k.kpp.config.thread;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.*;

/**
 * Thread configuration
 * Usage:
 * <pre> {@code
 *  @Autowired
 *  private ExecutorService executorService;
 *  executorService.execute(new Runnable() {
 *      @Override
 *      public void run() {
 *      System.out.println("run");
 *      }
 *  });
 *  executorService.submit(new Callable<String>() {
 *   @Override
 *    public String call() throws Exception {
 *     return "ret value";
 *    }
 *  });
 *  </pre>
 *
 *
 * @author k.w.l
 */
@Configuration
public class ThreadConfig {

    @Bean
    @ConfigurationProperties("thread")
    public ThreadProperties getThreadProperties(){
        return new ThreadProperties();
    }

    @Bean
    @ConfigurationProperties("thread.pool")
    public ThreadProperties.Pool getThreadPoolProperties(){
        return new ThreadProperties.Pool();
    }

    @Bean(name = "namedThreadFactory")
    public ThreadFactory getThreadFactory(ThreadProperties threadProperties){
        System.out.println("\nthread.name:"+threadProperties.getName());
        return new ThreadFactoryBuilder().setNameFormat(threadProperties.getName()).setDaemon(true).build();
    }

    @Bean
    public ExecutorService getThreadPool(ThreadFactory namedThreadFactory,ThreadProperties.Pool pool){
        System.out.println(String.format(
                "thread.pool.corePoolSize:%s%n,thread.pool.maximumPoolSize:%s%n,thread.pool.keepAliveTime:%s%n",
                pool.getCorePoolSize(),pool.getMaximumPoolSize(),pool.getKeepAliveTime())
        );
        return new ThreadPoolExecutor(
                pool.getCorePoolSize(),
                pool.getMaximumPoolSize(),
                pool.getKeepAliveTime(),
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(),
                namedThreadFactory,
                new ThreadPoolExecutor.AbortPolicy());
    }
}

